import cv2
import numpy as np
import os
import matplotlib.pyplot as plt

def process_image(image_path):
    # 读取图像文件
    image = cv2.imread(image_path)

    # 将图像转换为灰度图
    grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 对灰度图进行全域阈值处理转化为二值图像，并打印转化后的图像
    threshold = 110
    _, binary_image = cv2.threshold(
        grayscale_image, threshold, 255, cv2.THRESH_BINARY_INV)

    # 创建元素结构，采用4*4的矩形元素
    kernel = np.ones((3, 3), np.uint8)

    # 进行腐蚀操作，迭代3次增强腐蚀效果
    eroded_img = cv2.erode(binary_image, kernel, iterations=3)

    dilated_img = cv2.dilate(eroded_img, kernel, iterations=2)  # 对图像进行膨胀操作

    # 中值滤波去除dilated_img的小白点
    median_img = cv2.medianBlur(dilated_img, 13)

    # 运用闭运算填充闭合区域
    kernel3 = np.ones((7, 7), np.uint8)
    closing_img = cv2.morphologyEx(
        median_img, cv2.MORPH_CROSS, kernel3, iterations=10)

    # canney边缘识别
    lower = 50
    upper = 200
    edges_no_blur = cv2.Canny(closing_img, lower, upper)

    img_blur = cv2.GaussianBlur(closing_img, (3, 3), 0)  # 高斯滤波
    edges_with_blur = cv2.Canny(img_blur, lower, upper)

    # 提取轮廓
    contours, _ = cv2.findContours(
        edges_with_blur, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 创建字符图像保存目录
    chars_dir = 'chars'
    if not os.path.exists(chars_dir):
        os.makedirs(chars_dir)

    count = 1
    for contour in contours:
        # 计算轮廓周长
        perimeter = cv2.arcLength(contour, True)
        print("轮廓周长：", perimeter)

        if perimeter > 600:
            # 获取轮廓的边界矩形
            x, y, w, h = cv2.boundingRect(contour)

            # 在原图上画出矩形
            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 5)

            # 提取并保存字符图像
            char_img = image[y:y + h, x:x + w]
            char_filename = os.path.join(chars_dir, f'{count}.png')
            cv2.imwrite(char_filename, char_img)
            count += 1

    return image, grayscale_image, binary_image, eroded_img, dilated_img, median_img, closing_img, edges_with_blur

def display_images(images, titles):
    fig, axs = plt.subplots(2, 4, figsize=(15, 10))

    for i, ax in enumerate(axs.flat):
        ax.imshow(images[i], cmap='gray')
        ax.set_title(titles[i])
        ax.axis('off')

    plt.tight_layout(pad=1)
    plt.show()

if __name__ == "__main__":
    image_path = 'D:/shuzi/hanzi/hanzi1.jpg'
    processed_image, grayscale_image, binary_image, eroded_img, dilated_img, median_img, closing_img, edges_with_blur = process_image(image_path)
    images = [grayscale_image, binary_image, eroded_img, dilated_img, median_img, closing_img, edges_with_blur, processed_image]
    titles = ['Grayscale Image', 'Binary Image', 'Eroded Image', 'Dilated Image', 'Median Image', 'Closing Img', 'Edges with Blur', 'Bounding Box']
    display_images(images, titles)
